using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Audio;
using ShootThemUp.Sources.Configuration;

namespace ShootThemUp.Sources.AudioElements
{
    public class Audio
    {
        #region Constant fields

        /// <summary>
        /// The path to the menu song.
        /// </summary>
        private const string MENU_PATH = @"Game\Audios\Songs\menu";
        /// <summary>
        /// The path to the game song.
        /// </summary>
        private const string GAME_PATH = @"Game\Audios\Songs\game";
        /// <summary>
        /// The path to the rick roll song.
        /// </summary>
        private const string RICK_ROLL_PATH = @"Game\Audios\Songs\Extras\RickRoll";
        /// <summary>
        /// The path to the chocolate rain song.
        /// </summary>
        private const string CHOCOLATE_RAIN_PATH = @"Game\Audios\Songs\Extras\ChocolateRain";
        /// <summary>
        /// The path to the trololo song.
        /// </summary>
        private const string TROLOLO_PATH = @"Game\Audios\Songs\Extras\Trololo";
        /// <summary>
        /// The path to the What is Love song.
        /// </summary>
        private const string WHAT_IS_LOVE_PATH = @"Game\Audios\Songs\Extras\WhatIsLove";
        /// <summary>
        /// The path to the boss song.
        /// </summary>
        private const string BOSS_PATH = @"Game\Audios\Songs\boss";
        /// <summary>
        /// The pew-pew sound effect.
        /// </summary>
        private const string PLAYER_PEW_PATH = @"Game\Audios\SoundEffects\PlayerPew";
        /// <summary>
        /// The ball shot sound effect.
        /// </summary>
        private const string PLAYER_BALL_PATH = @"Game\Audios\SoundEffects\PlayerBall";
        /// <summary>
        /// The explosion sound effect.
        /// </summary>
        private const string EXPLOSION_PATH = @"Game\Audios\SoundEffects\explosion";
        /// <summary>
        /// The end song
        /// </summary>
        private const string END_PATH = @"Game\Audios\Songs\end";
        /// <summary>
        /// the path of the pineApple
        /// </summary>
        private const string PINEAPPLE_PATH = @"Game\Audios\SoundEffects\Pineapple";
        /// <summary>
        /// The path of the menu click sound
        /// </summary>
        private const string MENU_SOUND_PATH = @"Menus\Audios\jump_menu";
        private const string OPTION_SOUND_PATH = @"Game\Audios\SoundEffects\souffle_air";
        /// <summary>
        /// The default volume of the songs (menu, game and boss)
        /// </summary>
        public const float SONG_VOLUME = 1;
        /// <summary>
        /// The default volume of the sound effects.
        /// </summary>
        public const float SOUNDEFFECT_VOLUME = 0.35f;

        #endregion

        #region Fields

        //singleton pattern
        static Audio instance = null;

        /// <summary>
        /// The song played during the menu screen.
        /// </summary>
        private Song menu;
        /// <summary>
        /// The song played during the gameplay screen.
        /// </summary>
        private Song game;
        /// <summary>
        /// The song played during the gameplay screen. Trololo Mode.
        /// </summary>
        private Song trololoGame;
        /// <summary>
        /// The song played during the gameplay screen. RickRoll Mode.
        /// </summary>
        private Song rickRollGame;
        /// <summary>
        /// The song played during the gameplay screen. Chocolate rain Mode.
        /// </summary>
        private Song chocolateRainGame;
        /// <summary>
        /// The song played during the gameplay screen. What is Love Mode.
        /// </summary>
        private Song whatIsLoveGame;
        /// <summary>
        /// The song played during the boss fight.
        /// </summary>
        private Song boss;
        /// <summary>
        /// The sound effect play when the player fire a simple shot.
        /// </summary>
        private SoundEffect playerPew;
        /// <summary>
        /// The sound effect play when the player fire a ball shot.
        /// </summary>
        private SoundEffect playerBall;
        /// <summary>
        /// The sound effect play when the player die
        /// </summary>
        private SoundEffect explosion;
        /// <summary>
        /// The end song
        /// </summary>
        private Song end;
        /// <summary>
        /// 
        /// </summary>
        private SoundEffect pineApple;
        /// <summary>
        /// 
        /// </summary>
        private SoundEffect menu_click;
        private SoundEffect option_click;

        #endregion

        #region Properties

        /// <summary>
        /// Gets the get instance of this audio singleton.
        /// </summary>
        public static Audio GetInstance
        {
            get
            {
                if (instance == null)
                    instance = new Audio();

                return instance;
            }
        }

        /// <summary>
        /// Gets or sets the song played during the menu screen.
        /// </summary>
        /// <value>
        /// The menu song.
        /// </value>
        public Song Menu
        {
            get { return menu; }
            set { menu = value; }
        }

        /// <summary>
        /// Gets the song played during the gameplay screen, in function of the song choose in the options.
        /// </summary>
        public Song Game
        {
            get 
            { 
                Song gameSong = game;

                if (PlayerConfiguration.Song == ExtraSong.Trololo)
                    gameSong = trololoGame;
                else if (PlayerConfiguration.Song == ExtraSong.RickRoll)
                    gameSong = rickRollGame;
                else if (PlayerConfiguration.Song == ExtraSong.ChocolateRain)
                    gameSong = chocolateRainGame;
                else if (PlayerConfiguration.Song == ExtraSong.WhatIsLove)
                    gameSong = whatIsLoveGame;
                else if(PlayerConfiguration.Song == ExtraSong.None)
                    gameSong = null;

                return gameSong;
            }
        }

        /// <summary>
        /// Gets or sets the song played during the boss fight.
        /// </summary>
        /// <value>
        /// The boss song.
        /// </value>
        public Song Boss
        {
            get { return boss; }
            set { boss = value; }
        }

        /// <summary>
        /// Gets or sets the sound effect play when the player fire a simple shot.
        /// </summary>
        /// <value>
        /// The player pew pew sound effect.
        /// </value>
        public SoundEffect PlayerPew
        {
            get { return playerPew; }
            set { playerPew = value; }
        }

        /// <summary>
        /// Gets or sets the sound effect play when the player fire a ball shot.
        /// </summary>
        /// <value>
        /// The player ball sound effect.
        /// </value>
        public SoundEffect PlayerBall
        {
            get { return playerBall; }
            set { playerBall = value; }
        }

        /// <summary>
        /// Gets or sets the explosion.
        /// </summary>
        /// <value>
        /// The explosion.
        /// </value>
        public SoundEffect Explosion
        {
            get { return this.explosion; }
            set { this.explosion = value; }
        }

        public Song End {
            get { return this.end; }
            set { this.end = value; }
        }

        public SoundEffect PineApple { 
            get { return this.pineApple; }
            set { this.pineApple = value; }
        }

        public SoundEffect Menu_Click {
            get { return this.menu_click; }
            set { this.menu_click = value; }
        }

        public SoundEffect Option_Click
        {
            get { return this.option_click; }
            set { this.option_click = value; }
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Prevents a default instance of the <see cref="Audio"/> class from being created because Audio is a singleton.
        /// </summary>
        private Audio() { }

        #endregion

        #region Init

        /// <summary>
        /// Loads the sound asset.
        /// </summary>
        /// <param name="content">The content manager.</param>
        public void LoadSound(ContentManager content)
        {
            menu = content.Load<Song>(Audio.MENU_PATH);            
            game = content.Load<Song>(Audio.GAME_PATH);
            boss = content.Load<Song>(Audio.BOSS_PATH);
            rickRollGame = content.Load<Song>(Audio.RICK_ROLL_PATH);
            chocolateRainGame = content.Load<Song>(Audio.CHOCOLATE_RAIN_PATH);
            trololoGame = content.Load<Song>(Audio.TROLOLO_PATH);
            whatIsLoveGame = content.Load<Song>(Audio.WHAT_IS_LOVE_PATH);
            playerPew = content.Load<SoundEffect>(Audio.PLAYER_PEW_PATH);
            playerBall = content.Load<SoundEffect>(Audio.PLAYER_BALL_PATH);
            explosion = content.Load<SoundEffect>(Audio.EXPLOSION_PATH);
            end = content.Load<Song>(Audio.END_PATH);
            pineApple = content.Load<SoundEffect>(Audio.PINEAPPLE_PATH);
            menu_click = content.Load<SoundEffect>(Audio.MENU_SOUND_PATH);
            option_click = content.Load<SoundEffect>(Audio.OPTION_SOUND_PATH);
        }

        #endregion
    }
}
